"""
管理员 登录 注册 视图
"""

from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from app01.utils.form import LoginForm, AdminModelForm
from app01 import models
from app01.utils.code import check_code
from io import BytesIO


@csrf_exempt
def login(request):
    """登录"""
    if request.method == 'GET':
        # 前端不需要GET请求，直接返回错误
        return JsonResponse({
            'code': 405,
            'message': '方法不允许'
        }, status=405)

    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 验证码的校验
        user_input_code = form.cleaned_data.pop('code')
        code = request.session.get('image_code', '')
        if code.upper() != user_input_code.upper():
            return JsonResponse({
                'code': 400,
                'message': '验证码错误'
            }, status=400)

        # 去数据库校验用户名和密码是否正确，获取用户对象 / None
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            return JsonResponse({
                'code': 400,
                'message': '用户名或密码错误'
            }, status=400)

        # 用户名和密码正确
        # 网站生成随机字符串; 写到用户浏览器的cookie中；在写入到session中；
        request.session['info'] = {'id': admin_object.id, 'name': admin_object.username}

        # session可以保存7天
        request.session.set_expiry(60 * 60 * 24 * 7)

        return JsonResponse({
            'code': 200,
            'message': '登录成功',
            'data': {
                'userInfo': {
                    'id': admin_object.id,
                    'username': admin_object.username
                }
            }
        })

    # 表单验证失败
    errors = {}
    for field, error_list in form.errors.items():
        errors[field] = error_list[0]
    
    return JsonResponse({
            'code': 400,
            'message': '表单验证失败',
            'data': {
                'errors': errors
            }
        }, status=400)


def image_code(request):
    """生成图片验证码"""

    # 调用pillow函数，生成图片
    img, code_string = check_code()

    # 写入到自己的session中（以便后续获取验证码再进行校验）
    request.session['image_code'] = code_string

    # 给session设置60s超时
    request.session.set_expiry(60)

    # 把图片写入到内存中
    stream = BytesIO()
    img.save(stream, 'png')

    return HttpResponse(stream.getvalue(), content_type='image/png')


@csrf_exempt
def logout(request):
    """注销"""
    request.session.clear()
    return JsonResponse({
        'code': 200,
        'message': '注销成功'
    })


@csrf_exempt
def register(request):
    """注册（添加管理员）"""
    if request.method == 'GET':
        # 前端不需要GET请求，直接返回错误
        return JsonResponse({
            'code': 405,
            'message': '方法不允许'
        }, status=405)

    form = AdminModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        return JsonResponse({
            'code': 200,
            'message': '注册成功'
        })
    
    # 表单验证失败
    errors = {}
    for field, error_list in form.errors.items():
        errors[field] = error_list[0]
    
    return JsonResponse({
            'code': 400,
            'message': '注册失败',
            'data': {
                'errors': errors
            }
        }, status=400)

